// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993-1995  Microsoft Corporation.  All Rights Reserved.
//
//  MODULE:     REOleCb.cpp
//
//  PURPOSE:    <???>
//
//  PLATFORMS: 	Windows 95, Windows NT
//
//  FUNCTIONS:
//      <???> - <???>
//
//  COMMENTS:
//      <???>
//
//

#include <vcl.h>
#include <eic.h>
//#include <commctrl.h>
//#include <oledlg.h>
#pragma hdrstop
#include "REOleCb.h"
#define MODULE_TAG MODULE_TAG_ReOLECB
#undef TRACE
#define TRACE
/////////////////////////////////////////////////////////////////////////////
// IUnknown Interface members
//

STDMETHODIMP CRichEditOleCallback::QueryInterface(REFIID riid, LPVOID* ppv)
{
   	*ppv = NULL;
	TRACE(TEXT("CRichEditOleCallback::QueryInterface() returns "));

	if (IID_IUnknown == riid)
	{
		TRACE(TEXT("IUnknown."));
		*ppv = (LPUNKNOWN) this;
	}
	else if (IID_IRichEditOleCallback == riid)
	{
		TRACE(TEXT("IRichEditOleCallback."));
		*ppv = (LPRICHEDITOLECALLBACK) this;
	}
	else
	{
	 	TRACE(TEXT("E_NOINTERFACE."));
	}

	if (NULL == *ppv)
		return ResultFromScode(E_NOINTERFACE);

	((LPUNKNOWN) *ppv)->AddRef();
	return NOERROR;
}

STDMETHODIMP_(ULONG) CRichEditOleCallback::AddRef(void)
{
	m_cRef++;
	TRACE(TEXT("CRichEditOleCallback::AddRef().  Count = %d."),
			   m_cRef);
	return m_cRef;
}

STDMETHODIMP_(ULONG) CRichEditOleCallback::Release(void)
{
	m_cRef--;
	TRACE(TEXT("CRichEditOleCallback::Release().  Count = %d."),
			   m_cRef);

	if (0 == m_cRef)
		delete this;

	return m_cRef;
}


/////////////////////////////////////////////////////////////////////////////
// IRichEditOleCallback Interface Members
//

//
//  FUNCTION:   CRichEditOleCallback::GetNewStorage
//
//  PURPOSE:    Gets a storage for a new object.
//
//  PARAMETERS:
//      ppStg - Where to return the storage.
//
//  RETURN VALUE:
//      Returns an HRESULT signifying success or failure.
//
//  COMMENTS:
//      Implemented in the document object.
//

STDMETHODIMP CRichEditOleCallback::GetNewStorage(LPSTORAGE* ppStg)
{
	TRACE(TEXT("CRichEditOleCallback::GetNewStorage()"));

    if (!ppStg)
        return E_INVALIDARG;

    *ppStg = NULL;

    //
    // We need to create a new storage for an object to occupy.  We're going
    // to do this the easy way and just create a storage on an HGLOBAL and let
    // OLE do the management.  When it comes to saving things we'll just let
    // the RichEdit control do the work.  Keep in mind this is not efficient,
    // but this program is just for demonstration.
    //

    LPLOCKBYTES pLockBytes;
    HRESULT hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes);
    if (FAILED(hr)) return hr;

    hr = StgCreateDocfileOnILockBytes(pLockBytes,
                                      STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE,
                                      0,
                                      ppStg);
    pLockBytes->Release();
    return (hr);
}


//
//  FUNCTION:   CRichEditOleCallback::GetInPlaceContext
//
//  PURPOSE:    Gets the context information for an in place object.
//
//  PARAMETERS:
//      ppFrame    - Pointer to the frame window object.
//		ppDoc      - Pointer to the document window object.
//		pFrameInfo - Pointer to the frame window information.
//
//  RETURN VALUE:
//      Returns an HRESULT signifying success or failure.
//
//

STDMETHODIMP CRichEditOleCallback::GetInPlaceContext(LPOLEINPLACEFRAME* ppFrame,
												LPOLEINPLACEUIWINDOW* ppDoc,
												LPOLEINPLACEFRAMEINFO pFrameInfo)
{
	TRACE(TEXT("CRichEditOleCallback::GetInPlaceContext()"));

	//
	// Validate the arguments
	//
	if (!ppFrame || !ppDoc || !pFrameInfo)
	{
		TRACE(TEXT("CRichEditOleCallback::GetInPlaceContext() received an")
			  TEXT(" invalid argument."));
		return E_INVALIDARG;
	}

/*	//
	// Return the appropriate interface pointers.
	//
	*ppDoc = (LPOLEINPLACEUIWINDOW) m_pDoc->GetInPlaceFrame();
    if (*ppDoc)
	    (*ppDoc)->AddRef();

	*ppFrame = m_pDoc->GetInPlaceFrame();
	if (*ppFrame)
		(*ppFrame)->AddRef();

	//
	// Fill in the default frame window information.
	//
	pFrameInfo->fMDIApp = FALSE;
	pFrameInfo->hwndFrame = m_pDoc->GetFrameWindow();
	pFrameInfo->haccel = m_pDoc->GetInPlaceAccel();

	//
	// Note: CopyAcceleratorTable() returns the number of items in the table
	// 	     if the	lpAccelDest is NULL.
	//
	pFrameInfo->cAccelEntries = CopyAcceleratorTable(pFrameInfo->haccel,
													 NULL, 0);*/

	return S_OK;
}


//
//  FUNCTION:	CRichEditOleCallback::ShowContainerUI
//
//  PURPOSE:	Handles the showing or hiding of the container UI.
//
//  PARAMETERS:
//      fShow - TRUE if the function should display the UI, FALSE to hide it.
//
//  RETURN VALUE:
//      Returns an HRESULT signifying success or failure.
//

STDMETHODIMP CRichEditOleCallback::ShowContainerUI(BOOL fShow)
{
	TRACE(TEXT("CRichEditOleCallback::ShowContainerUI()"));

/*	if (!m_pDoc->GetInPlaceFrame()) 	// This should never fail, but just in case...
		return E_FAIL;

	if (fShow)
	{
		(m_pDoc->GetInPlaceFrame())->ReinstateUI();
		//SetFocus(m_hwndEdit);
	}
	else
		(m_pDoc->GetInPlaceFrame())->ShowUIAndTools(FALSE, FALSE);*/

	return S_OK;
}


//
//  FUNCTION:	CRichEditOleCallback::QueryInsertObject
//
//  PURPOSE:    Called to ask whether an object should be inserted.  We're
//				going to allow everything to be inserted.
//

STDMETHODIMP CRichEditOleCallback::QueryInsertObject(LPCLSID /* pclsid */,
												LPSTORAGE /* pStg */,
												LONG /* cp */)
{
	TRACE(TEXT("CRichEditOleCallback::QueryInsertObject()"));
	return S_OK;
}


//
//  FUNCTION:   CRichEditOleCallback::DeleteObject
//
//  PURPOSE:    Notification that an object is going to be deleted.
//

STDMETHODIMP CRichEditOleCallback::DeleteObject( LPOLEOBJECT /* pOleObj */)
{
	TRACE(TEXT("CRichEditOleCallback::DeleteObject( )"));
	return S_OK;
}


//
//  FUNCTION:   CRichEditOleCallback::QueryAcceptData
//
//  PURPOSE:    Called to ask whether the data that is being pasted or
//				dragged should be accepted.  We accept everything.
//

STDMETHODIMP CRichEditOleCallback::QueryAcceptData(LPDATAOBJECT /* pDataObj */,
											  CLIPFORMAT* /* pcfFormat */,
											  DWORD /* reco */,
											  BOOL /* fReally */,
											  HGLOBAL /* hMetaPict */)
{
	TRACE(TEXT("CRichEditOleCallback::QueryAcceptData()"));
	return S_OK;
}


//
//  FUNCTION:   CRichEditOleCallback::ContextSensitiveHelp
//
//  PURPOSE:    Tells the application that it should transition into or out of
//				context sensitive help mode.  We don't implement help at all
//				so blow this off.
//

STDMETHODIMP CRichEditOleCallback::ContextSensitiveHelp(BOOL fEnterMode)
{
	TRACE(TEXT("CRichEditOleCallback::ContextSensitveHelp()"));
	return E_NOTIMPL;
}


//
//  FUNCTION:   CRichEditOleCallback::GetClipboardData
//
//  PURPOSE:    Called when the rich edit needs to provide clipboard data.
//				We'll let the rich edit control handle this one.
//

STDMETHODIMP CRichEditOleCallback::GetClipboardData(CHARRANGE* /* pchrg */,
											   DWORD /* reco */,
											   LPDATAOBJECT* ppDataObject)

{
	TRACE(TEXT("CRichEditOleCallback::GetClipboardData()"));
   	*ppDataObject = NULL;
	return E_NOTIMPL;
}


//
//  FUNCTION:   CRichEditOleCallback::GetDragDropEffect
//
//  PURPOSE:    Allows us to determine the drag cursor effect when the user
//				is dragging something over us.  We'll let the rich edit control
//				handle this one as well.
//

STDMETHODIMP CRichEditOleCallback::GetDragDropEffect(BOOL /* fDrag */,
												DWORD /* grfKeyState */,
												LPDWORD /* pdwEffect */)
{
	TRACE(TEXT("CRichEditOleCallback::GetDragDropEffect()"));
	return E_NOTIMPL;
}


//
//  FUNCTION:   CRichEditOleCallback::GetContextMenu
//
//  PURPOSE:    Creates the context menu for alternate mouse clicks in the
//				RichEdit control.
//
//  PARAMETERS:
//      seltype - Selection type
//		pOleObj - IOleObject interface of the selected object, if any
//		pchrg   - Selection range
//		phMenu  - Place to return the constructed menu
//
//  RETURN VALUE:
//      Returns an HRESULT signifying success or failure.
//

STDMETHODIMP CRichEditOleCallback::GetContextMenu(WORD seltype,
											 LPOLEOBJECT pOleObj,
											 CHARRANGE* pchrg,
											 HMENU* phMenu)
{
	TRACE(TEXT("CRichEditOleCallback::GetContextMenu()"));

	//
	// First create the menu.
	//
/*	*phMenu = CreatePopupMenu();
	if (!*phMenu)
		return E_FAIL;

	//
	// Now put the verbs on the menu if we have a selected object.
	//
	if (pOleObj)
	{
		OleUIAddVerbMenu(pOleObj, NULL, *phMenu, 0, IDM_VERBMIN,
						 IDM_VERBMAX, TRUE, ID_EDIT_CONVERT,
						 &hMenuVerbs);

		AppendMenu(*phMenu, MF_SEPARATOR, 0, NULL);
	}

	//
	// If there isn't anything selected, then gray out the cut and copy
	// menu items.
	//
	UINT mf = MF_STRING | MF_BYCOMMAND;
	mf |= (pchrg->cpMin == pchrg->cpMax ? MF_GRAYED : MF_ENABLED);

	//
    // Add the cut, copy, and paste verbs.
	//
	AppendMenu(*phMenu, mf, ID_EDIT_CUT, TEXT("Cu&t"));
	AppendMenu(*phMenu, mf, ID_EDIT_COPY, TEXT("&Copy"));

	//
	// Now decide if there is something that can be pasted into the Rich Edit
	// control.
	//
	mf = MF_STRING | MF_BYCOMMAND;
	mf |= (SendMessage(m_hwndEdit, EM_CANPASTE, 0, 0) ? 
                       MF_ENABLED : MF_GRAYED);
	AppendMenu(*phMenu, mf, ID_EDIT_PASTE, TEXT("&Paste"));    */

	return S_OK;
}




